import msg
import MySQLdb
import urllib

def showPlayer(info):
	#id, name, alliance_id, points, rank, towns
	msg.show('-'*40, 'black', 1)
	msg.show('Player Profile', 'yellow', 1);
	msg.show('ID: '); msg.show(str(info[0]), 'blue', 1)
	msg.show('Name: '); msg.show(urllib.unquote(info[1]).replace('+', ' '), 'blue', 1)
	msg.show('Points: '); msg.show(str(info[3]), 'blue', 1)
	msg.show('Rank: '); msg.show(str(info[4]), 'blue', 1)
	
	# Alliance
	msg.show('Alliance: ')
	ally = get('alliances', info[2])
	if len(ally) == 0: msg.show('', 'blue', 1)
	else: msg.show(urllib.unquote(ally[0][1]).replace('+', ' '), 'blue', 1)
	
	# Towns
	msg.show('Towns: '); msg.show(str(info[5]), 'blue', 1)
	
	# Link
	msg.show('Link: ' )
	msg.show('http://en4.grepolis.com/game/player?player_id={0}'.format(info[0]), 'blue', 1)
	
	# Related Towns
	towns = {}
	msg.show('-'*40, 'black', 1)
	msg.show('Related Towns', 'yellow', 1)
	
	# Towns
	properties = get('towns', info[0], 'player_id')
	for prop in properties:
		towns[prop[0]] = {}
		towns[prop[0]]['info'] = prop
		towns[prop[0]]['status'] = '*'
	
	# Conquers
	conquers = get('conquers', info[0], ['old_player_id', 'new_player_id'])
	for conquer in conquers:
		towns[conquer[0]] = {}
		towns[conquer[0]]['info'] = get('towns', conquer[0])[0]
		if info[0] == conquer[2]:
			towns[conquer[0]]['status'] = '+'
		elif info[0] == conquer[3]:
			towns[conquer[0]]['status'] = '-'
	
	for k, town in towns.iteritems():
		# Conquer Status
		if town['status'] == '*': msg.show(' * ', 'black', bold=True) # Original Town
		elif town['status'] == '+': msg.show(' + ', 'green', bold=True) # Acquired Town
		elif town['status'] == '-': msg.show(' - ', 'red', bold=True) # Lost Town
		
		# Ocean
		ocean = '{0}{1} '.format(str(town['info'][3])[0:1], str(town['info'][4])[0:1])
		msg.show(ocean, 'cyan')
		
		# Coords
		coords = '({0}, {1}) '.format(town['info'][3], town['info'][4])
		msg.show(coords, 'purple')
		
		# ID
		msg.show('[{0}] '.format(town['info'][0]), 'white')
		
		# Name
		msg.show('{0}'.format(urllib.unquote(town['info'][2]).replace('+', ' ')), 'blue')
		
		# Points
		msg.show(' {0} '.format(town['info'][6]), 'yellow', 1)
	
	msg.show('-'*40, 'black', 1)

def showTown(info):
	msg.show('-'*40, 'black', 1)
	msg.show('Town Profile', 'yellow', 1);
	msg.show('ID: '); msg.show(str(info[0]), 'blue', 1)
	msg.show('Name: '); msg.show(urllib.unquote(info[2]).replace('+', ' '), 'blue', 1)
	msg.show('Points: '); msg.show(str(info[6]), 'blue', 1)
	
	# Player
	player = get('players', info[1])
	if not player:
		msg.show('Player: '); msg.show('abandoned', 'white', 1, bold=True)
	else:
		msg.show('Player: '); msg.show(urllib.unquote(player[0][1]).replace('+', ' '), 'blue', 1)
	
	# Ocean
	ocean = '{0}{1} '.format(str(info[3])[0:1], str(info[4])[0:1])
	msg.show('Ocean: '); msg.show(ocean, 'blue', 1)
	
	# Coords
	coords = '({0}, {1}) '.format(info[3], info[4])
	msg.show('Coords: '); msg.show(coords, 'blue', 1)
	
	# Link
	msg.show('Link: ')
	msg.show('http://en4.grepolis.com/game/map?target_town_id={0}'.format(info[0]), 'blue', 1)
	
	msg.show('-'*40, 'black', 1)

def showAlliance(info):
	#id, name, points, villages, members, rank
	msg.show('-'*40, 'black', 1)
	msg.show('Alliance Profile', 'yellow', 1);
	msg.show('ID: '); msg.show(str(info[0]), 'blue', 1)
	msg.show('Name: '); msg.show(urllib.unquote(info[1]).replace('+', ' '), 'blue', 1)
	msg.show('Rank: '); msg.show(str(info[5]), 'blue', 1)
	
	msg.show('Points: '); msg.show(str(info[2]), 'blue')
	msg.show(' (town:{0} /'.format(info[2] / info[3]), 'purple')
	msg.show(' member:{0}) '.format(info[2] / info[4]), 'purple', 1)
	
	msg.show('Towns: '); msg.show(str(info[3]), 'blue', 1)
	msg.show('Members: '); msg.show(str(info[4]), 'blue', 1)
	
	msg.show('-'*40, 'black', 1)
	
	# Top Members
	msg.show('Top Members', 'yellow', 1);
	sql = 'SELECT * FROM players WHERE alliance_id = {0} ORDER BY points DESC LIMIT 10'.format(info[0])
	members = query(sql)
	for member in members:
		msg.show('[{0}] '.format(member[0]), 'black')
		msg.show('{0} '.format(member[1]), 'blue')
		msg.show('( {0} ) '.format(member[3]), 'purple')
		msg.show('({0})'.format(member[5]), 'blue', 1)
	
	msg.show('-'*40, 'black', 1)

def query(sql):
	conn = MySQLdb.connect(host='localhost', user='root', passwd='', db='defcon')
	conn.query(sql)
	rs = conn.store_result().fetch_row(maxrows=10)
	conn.close()
	return rs
	
def getOcean(island_id):
	conn = MySQLdb.connect(host='localhost', user='root', passwd='', db='defcon')
	sql = 'SELECT * FROM islands WHERE id = {0}'.format(island_id)
	conn.query(sql)
	island = conn.store_result().fetch_row()[0]
	conn.close()
	return island
	
def get(what, value, by='id'):
	conn = MySQLdb.connect(host='localhost', user='root', passwd='', db='defcon')
	if type(by) == list:
		where = []
		for field in by:
			where.append('{0} = {1}'.format(field, value))
		sql = 'SELECT * FROM {0} WHERE {1}'.format(what, ' OR '.join(where))
	else:
		sql = 'SELECT * FROM {0} WHERE {1} = {2}'.format(what, by, value)
	try:
		conn.query(sql)
	except MySQLdb.Error as (errnum, errstr):
		msg.show('ERROR {0}: {1}'.format(errnum, errstr), 'red', 1)
		msg.show(sql, 'red', 1)
		conn.close()
		return
	hits = conn.store_result().fetch_row(maxrows=0)
	conn.close()
	return hits

def formatWhere(field, value):
	if type(value) == list or type(value) == tuple:
		where = []
		for atom in value:
			where.append(formatWhere(field, atom))
		return ' AND '.join(where)
	else:
		return '{0} LIKE "%{1}%"'.format(field, value)

def search(what, value):
	# Seek and destroy
	conn = MySQLdb.connect(host='localhost', user='root', passwd='', db='defcon')
	sql = 'SELECT * FROM {0} WHERE '.format(what)
	if len(value) > 1 and value[0] == '#':
		sql = sql + '{0} = "{1}"'.format('id', value[1])
	elif len(value) > 1 and what == 'towns' and (value[0] == 'o' or value[0] == 'ocean'):
		x = value[1][0:1]; y = value[1][1:2]
		sql = sql + 'island_x >= {0}00 and island_x <= {0}99 and island_y >= {1}00 and island_y <= {1}99'.format(x, y)
		if len(value) > 2 and (value[2] == 'a' or value[2] == 'abandoned'):
			msg.show('Abandoned Towns Lookup', 'yellow', 1)
			sql = sql + ' and player_id = 0'.format(value[2])
		elif len(value) > 2 and (value[2] == 'v' or value[2] == 'vulnerable'):
			msg.show('Vulnerable Towns Lookup', 'yellow', 1)
			sql = sql + ' and (select alliance_id from players where id = towns.player_id) = 0'.format(value[2])
		sql = sql + ' ORDER BY points DESC LIMIT 15'
	elif what == 'players' or what == 'alliances' or what == 'towns':
		sql = sql + formatWhere('name', value)
	try:
		conn.query(sql)
	except MySQLdb.Error as (errnum, errstr):
		msg.show('ERROR {0}: {1}'.format(errnum, errstr), 'red', 1)
		msg.show(sql, 'red', 1)
		return
	hits = conn.store_result().fetch_row(maxrows=0)
	conn.close()
	if len(hits) == 0:
		msg.show('No {0} Found'.format(what.capitalize()), 'red', 1)
	elif len(hits) > 1:
		msg.show('-'*40, 'black', 1)
		msg.show('{0} {1} Found:'.format(len(hits), what.capitalize()), 'yellow', 1)
		try:
			for p in hits:
				if what == 'players' or what == 'alliances':
					msg.show(urllib.unquote('[{0}] {1}'.format(*p)).replace('+', ' '), 'blue', 1)
				elif what == 'towns':
					# Ocean
					ocean = '{0}{1} '.format(str(p[3])[0:1], str(p[4])[0:1])
					msg.show(ocean, 'cyan')
	
					# Coords
					coords = '({0}, {1}) '.format(p[3], p[4])
					msg.show(coords, 'purple')
				
					# ID
					msg.show('[{0}] '.format(p[0]), 'white')
				
					#Player
					player = get('players', p[1])
					msg.show(urllib.unquote(str(p[2]).replace('+', ' ')), 'blue')
					if not player:
						msg.show(' abandoned', 'white', bold=True)
					else:
						msg.show(' ({0})'.format(urllib.unquote(player[0][1]).replace('+', ' ')), 'purple')

					# Points
					msg.show(' {0}'.format(p[6]), 'blue', 1)
		except KeyboardInterrupt:
			print ''; msg.show('Interrupted', 'red', 1)
				
		msg.show('-'*40, 'black', 1)
	else:
		if what == 'players': showPlayer(hits[0])
		if what == 'alliances': showAlliance(hits[0])
		if what == 'towns': showTown(hits[0])
	
def run(what, *params):
	if what == 'players' or what == 'player' or what == 'p':
		if len(params) == 0: msg.show('Not Enough Params', 'red', 1); return
		search('players', params)
	elif what == 'towns' or what == 'town' or what == 't':
		if len(params) == 0: msg.show('Not Enough Params', 'red', 1); return
		search('towns', params)
	elif what == 'alliances' or what == 'alliance' or what == 'ally' or what == 'a':
		if len(params) == 0: msg.show('Not Enough Params', 'red', 1); return
		search('alliances', params)
	elif what == 'islands' or what == 'island' or what == 'isle' or what == 'i':
		msg.show('Island Lookup Unavailable', 'red', 1)
	elif what == 'conquers' or what == 'conquer' or what == 'conq' or what == 'c':
		import conquests
		if len(params) == 2 and params[1] == 'bb':
			conquests.lookup(params[0], True)
		elif len(params) == 1:
			conquests.lookup(params[0], False)
		else:
			incorrectUsage()

def incorrectUsage():
	msg.show('Usage:', 'red', True)
	msg.show('\tlookup <player|town|alliance> <name>', 'red', True)
	msg.show('\tlookup conquers ocean', 'red', True)
